package com.xiaozhi.component;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

/**
 * 聊天性能监控组件
 * 记录和统计聊天请求的性能指标
 */
@Component
@Slf4j
public class ChatMetrics {
    
    // 请求计数器
    private final AtomicLong totalRequests = new AtomicLong(0);
    private final AtomicLong successfulRequests = new AtomicLong(0);
    private final AtomicLong failedRequests = new AtomicLong(0);
    
    // 响应时间统计
    private final AtomicLong totalResponseTime = new AtomicLong(0);
    private final AtomicReference<Long> maxResponseTime = new AtomicReference<>(0L);
    private final AtomicReference<Long> minResponseTime = new AtomicReference<>(Long.MAX_VALUE);
    
    // 最近的响应时间记录（用于计算移动平均）
    private final List<Long> recentResponseTimes = Collections.synchronizedList(new ArrayList<>());
    private static final int MAX_RECENT_RECORDS = 100;
    
    // 错误统计
    private final ConcurrentHashMap<String, AtomicLong> errorCounts = new ConcurrentHashMap<>();
    
    // 重试统计
    private final AtomicLong totalRetries = new AtomicLong(0);
    
    // 启动时间
    private final LocalDateTime startTime = LocalDateTime.now();
    
    /**
     * 记录请求开始
     * @return 请求开始时间戳
     */
    public long recordRequestStart() {
        totalRequests.incrementAndGet();
        return System.currentTimeMillis();
    }
    
    /**
     * 记录请求成功
     * @param startTime 请求开始时间戳
     * @param retryCount 重试次数
     */
    public void recordRequestSuccess(long startTime, int retryCount) {
        long responseTime = System.currentTimeMillis() - startTime;
        
        successfulRequests.incrementAndGet();
        totalResponseTime.addAndGet(responseTime);
        
        // 更新最大最小响应时间
        maxResponseTime.updateAndGet(current -> Math.max(current, responseTime));
        minResponseTime.updateAndGet(current -> Math.min(current, responseTime));
        
        // 记录最近的响应时间
        synchronized (recentResponseTimes) {
            recentResponseTimes.add(responseTime);
            if (recentResponseTimes.size() > MAX_RECENT_RECORDS) {
                recentResponseTimes.remove(0);
            }
        }
        
        // 记录重试次数
        if (retryCount > 0) {
            totalRetries.addAndGet(retryCount);
        }
        
        log.info("聊天请求成功 - 响应时间: {}ms, 重试次数: {}", responseTime, retryCount);
    }
    
    /**
     * 记录请求失败
     * @param startTime 请求开始时间戳
     * @param errorType 错误类型
     * @param retryCount 重试次数
     */
    public void recordRequestFailure(long startTime, String errorType, int retryCount) {
        long responseTime = System.currentTimeMillis() - startTime;
        
        failedRequests.incrementAndGet();
        
        // 记录错误类型
        errorCounts.computeIfAbsent(errorType, k -> new AtomicLong(0)).incrementAndGet();
        
        // 记录重试次数
        if (retryCount > 0) {
            totalRetries.addAndGet(retryCount);
        }
        
        log.warn("聊天请求失败 - 响应时间: {}ms, 错误类型: {}, 重试次数: {}", 
                responseTime, errorType, retryCount);
    }
    
    /**
     * 获取性能统计信息
     * @return 性能统计Map
     */
    public Map<String, Object> getMetrics() {
        Map<String, Object> metrics = new ConcurrentHashMap<>();
        
        long total = totalRequests.get();
        long successful = successfulRequests.get();
        long failed = failedRequests.get();
        
        // 基本统计
        metrics.put("totalRequests", total);
        metrics.put("successfulRequests", successful);
        metrics.put("failedRequests", failed);
        metrics.put("successRate", total > 0 ? (double) successful / total * 100 : 0.0);
        
        // 响应时间统计
        if (successful > 0) {
            metrics.put("averageResponseTime", (double) totalResponseTime.get() / successful);
            metrics.put("maxResponseTime", maxResponseTime.get());
            metrics.put("minResponseTime", minResponseTime.get() == Long.MAX_VALUE ? 0 : minResponseTime.get());
            
            // 最近请求的平均响应时间
            synchronized (recentResponseTimes) {
                if (!recentResponseTimes.isEmpty()) {
                    double recentAverage = recentResponseTimes.stream()
                            .mapToLong(Long::longValue)
                            .average()
                            .orElse(0.0);
                    metrics.put("recentAverageResponseTime", recentAverage);
                }
            }
        } else {
            metrics.put("averageResponseTime", 0.0);
            metrics.put("maxResponseTime", 0L);
            metrics.put("minResponseTime", 0L);
            metrics.put("recentAverageResponseTime", 0.0);
        }
        
        // 重试统计
        metrics.put("totalRetries", totalRetries.get());
        metrics.put("averageRetriesPerRequest", total > 0 ? (double) totalRetries.get() / total : 0.0);
        
        // 错误统计
        Map<String, Long> errors = new ConcurrentHashMap<>();
        errorCounts.forEach((key, value) -> errors.put(key, value.get()));
        metrics.put("errorBreakdown", errors);
        
        // 运行时间
        metrics.put("startTime", startTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        metrics.put("uptime", java.time.Duration.between(startTime, LocalDateTime.now()).toString());
        
        return metrics;
    }
    
    /**
     * 重置所有统计信息
     */
    public void reset() {
        totalRequests.set(0);
        successfulRequests.set(0);
        failedRequests.set(0);
        totalResponseTime.set(0);
        maxResponseTime.set(0L);
        minResponseTime.set(Long.MAX_VALUE);
        totalRetries.set(0);
        
        synchronized (recentResponseTimes) {
            recentResponseTimes.clear();
        }
        
        errorCounts.clear();
        
        log.info("聊天性能统计已重置");
    }
    
    /**
     * 获取简化的性能摘要
     * @return 性能摘要字符串
     */
    public String getMetricsSummary() {
        long total = totalRequests.get();
        long successful = successfulRequests.get();
        double successRate = total > 0 ? (double) successful / total * 100 : 0.0;
        double avgResponseTime = successful > 0 ? (double) totalResponseTime.get() / successful : 0.0;
        
        return String.format("总请求: %d, 成功: %d, 成功率: %.1f%%, 平均响应时间: %.0fms", 
                total, successful, successRate, avgResponseTime);
    }
}